package com.yerbamateprimer.advice.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import com.google.common.base.Preconditions;
import com.yerbamateprimer.advice.MultipleReceptorAdvice;
import com.yerbamateprimer.model.User;

/**
 * This class models an advice
 * to let all the users know
 * that the primer changes.
 * 
 * @author Matias Liwski
 * @version 1.0
 */
public class PrimerChangedAdvice implements MultipleReceptorAdvice {
	private static final long serialVersionUID = 1296255640923937220L;
	private Set<User> receptors;
	private User primer;

	/**
	 * @param receptors The collection of receptors for this advice.
	 * @param primer The new primer of the round.
	 */
	public PrimerChangedAdvice(Collection<User> receptors, User primer) {
		this.receptors = new HashSet<User>();
		setPrimer(primer);
		addAllAdviceReceptors(receptors);
	}

	/* (non-Javadoc)
	 * @see com.yerbamateprimer.advice.MultipleReceptorAdvice#addReceptor(com.yerbamateprimer.model.User)
	 */
	@Override
	public void addAdviceReceptor(User adviceReceptor) {
		Preconditions.checkArgument(adviceReceptor != null, "Couldn't add a null receptor to this advice.");
		this.receptors.add(adviceReceptor);
	}

	/* (non-Javadoc)
	 * @see com.yerbamateprimer.advice.MultipleReceptorAdvice#addReceptors(java.util.List)
	 */
	@Override
	public void addAllAdviceReceptors(Collection<User> adviceReceptors) {
		Preconditions.checkArgument(adviceReceptors != null && !adviceReceptors.isEmpty(), "Couldn't add invalid receptors (receptors=" + adviceReceptors + ").");
		this.receptors.addAll(adviceReceptors);
	}

	/**
	 * A safe copy of advice receptors.
	 * @see com.yerbamateprimer.advice.MultipleReceptorAdvice#getAdviceReceptors()
	 */
	@Override
	public List<User> getAdviceReceptors() {
		return new ArrayList<User>(this.receptors);
	}

	/**
	 * @param primer The new primer of the round to set.
	 */
	public void setPrimer(User primer) {
		Preconditions.checkArgument(primer != null, "This advice need to know how is the primer.");
		this.primer = primer;
	}

	/**
	 * @return The new primer of the round.
	 */
	public User getPrimer() {
		return this.primer;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE, false, false);
	}
}